﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Threading;
using SuperSimpleTcp;
using Inspection.Helper;
using System.Runtime.CompilerServices;
using Infrastructure;

namespace Inspection.Views
{
    /// <summary>
    /// UCTcpClient.xaml 的交互逻辑
    /// </summary>
    public partial class UCTcpClient : UserControl, INotifyPropertyChanged
    {
        public UCTcpClient()
        {
            InitializeComponent();
            CommandBindings.Add(new CommandBinding(ConnetedCommand, Connect_Excute, Connect_CanExcute));
            CommandBindings.Add(new CommandBinding(SendCommand, Send_Excute, Send_CanExcute));
        }
        public static RoutedCommand ConnetedCommand = new RoutedCommand();
        public static RoutedCommand SendCommand = new RoutedCommand();

        #region 公有属性
        public static DependencyProperty ServerIPProperty = DependencyProperty.Register("ServerIP", typeof(string), typeof(UCTcpClient), new FrameworkPropertyMetadata("127.0.0.1", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, ProChanged));
        public static DependencyProperty PortProperty = DependencyProperty.Register("Port", typeof(int), typeof(UCTcpClient), new FrameworkPropertyMetadata(5000, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, ProChanged));
        public static DependencyProperty ClientProperty = DependencyProperty.Register("Client", typeof(SimpleTcpClient), typeof(UCTcpClient), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, ProChanged));

        /// <summary>
        /// IP地址
        /// </summary>
        public string ServerIP
        {
            get { return (string)GetValue(ServerIPProperty); }
            set { SetValue(ServerIPProperty, value); }
        }

        /// <summary>
        /// 端口号
        /// </summary>
        public int Port
        {
            get { return (int)GetValue(PortProperty); }
            set { SetValue(PortProperty, value); }
        }

        /// <summary>
        /// 发送的内容
        /// </summary>
        public string SendContent
        {
            get { return _sendContent; }
            set { _sendContent = value; OnPropertyChanged(); }
        }
        private string _sendContent = string.Empty;

        /// <summary>
        /// TCP客户端
        /// </summary>
        public SimpleTcpClient Client
        {
            get { return (SimpleTcpClient)GetValue(ClientProperty); }
            set { SetValue(ClientProperty, value); }
        }

        /// <summary>
        /// 按钮命令内容
        /// </summary>
        public string ConnectCom
        {
            get { return connectCom; }
            private set
            {
                if (value != connectCom)
                {
                    connectCom = value;
                    OnPropertyChanged();
                }
            }
        }
        private string connectCom = StrConnectCom;

        #endregion 公有属性

        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged([CallerMemberName] string PropertyName = null)
        {
            if (null != PropertyChanged)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
            }
        }
        #endregion INotifyPropertyChanged

        private static void ProChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UCTcpClient sendor = (UCTcpClient)d;
            if (null == sendor) return;
            bool isConnected = sendor.Client != null && sendor.Client.IsConnected;
            string nIp = string.Empty;
            int port = -1;
            if (e.Property == ServerIPProperty)
            {
                nIp = (string)e.NewValue;
                port = sendor.Port;
            }
            else if (e.Property == PortProperty)
            {
                nIp = sendor.ServerIP;
                port = (int)e.NewValue;
            }
            else if (e.Property == ClientProperty)
            {
                SimpleTcpClient oldclient = e.OldValue as SimpleTcpClient;
                SimpleTcpClient nclient = e.NewValue as SimpleTcpClient;
                if (null != oldclient && null != oldclient.Events)
                {
                    oldclient.Events.DataReceived -= sendor.TcpClient_DataReceived;
                    oldclient.Events.Connected -= sendor.Events_Connected;
                    oldclient.Events.Disconnected -= sendor.Events_Disconnected;           
                    oldclient.Logger = null;
                }
                if (null != nclient && null != nclient.Events)
                {
                    nclient.Events.DataReceived += sendor.TcpClient_DataReceived;
                    nclient.Events.Connected += sendor.Events_Connected;
                    nclient.Events.Disconnected += sendor.Events_Disconnected;
                    nclient.Logger = sendor.WriteLogToTxt;
                    string strPort = nclient.ServerIpPort;
                    string[] arry = strPort.Split(':');
                    if (null == arry || arry.Length != 2) return;
                    sendor.ServerIP = arry[0];
                    sendor.Port = int.Parse(arry[1]);
                }
            }
        }

        private void WriteLogToTxt(string strLog)
        {
            LogServiceHelper.Fatal(strLog);
        }

        private void ConnectClient(string strIP, int port)
        {
            if (!strIP.IsIpAdress())
            {
                recieveContent.Text += "IP格式设置错误,请设置正确的IP地址.....";
                return;
            }
            if (null != Client && Client.IsConnected)
            {
                if (Client.ServerIpPort == $"{strIP}:{port}") return;
                Client.Disconnect();
            }
            Client = new SimpleTcpClient(ServerIP, Port);
            try
            {
                Client.Connect();
            }
            catch (Exception ex)
            {
                GlobalLogMessageEvent.Publish(new MessageData(MessageType.Error, $"与服务器{ServerIP}端口={Port}通讯连接失败"));
            }
        }

        private void Connect_Excute(object sender, ExecutedRoutedEventArgs e)
        {
            if (null == Client || !Client.IsConnected)
            {
                ConnectClient(ServerIP, Port);
            }
            else
            {
                Client.Dispose();
            }
        }

        private void Connect_CanExcute(object sender, CanExecuteRoutedEventArgs e)
        {
            ConnectCom = null == Client || !Client.IsConnected ? StrConnectCom : StrDisConnectCom;
            if ((null == Client || !Client.IsConnected) && string.IsNullOrEmpty(ServerIP))
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void Send_Excute(object sender, ExecutedRoutedEventArgs e)
        {
            Client.Send(_sendContent);

        }

        private void Send_CanExcute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = null != Client && Client.IsConnected && !string.IsNullOrEmpty(_sendContent);
        }

        private void Events_Disconnected(object sender, ConnectionEventArgs e)
        {
            Dispatcher.Invoke(() =>
            {
                recieveContent.Text += $"与服务器{ServerIP}端口={Port}断开连接\r\n";
            });
        }

        private void Events_Connected(object sender, ConnectionEventArgs e)
        {
            Dispatcher.Invoke(() =>
            {
                recieveContent.Text += $"与服务器{ServerIP}端口={Port}连接成功\r\n";
            });
        }

        private void TcpClient_DataReceived(object sender, DataReceivedEventArgs e)
        {
            if (e == null || e.Data == null) return;
            Dispatcher.Invoke(() =>
            {
                string data = Encoding.UTF8.GetString(e.Data.Array).Trim();
                recieveContent.Text += $"{data}\r\n";
            });
        }

        private void clar_Click(object sender, RoutedEventArgs e)
        {
            recieveContent.Clear();
        }

        private const string StrConnectCom = "连接";
        private const string StrDisConnectCom = "断开连接";
    }
}
